package com.ocom.human.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ocom.common.constant.UserConstants;
import com.ocom.common.dto.AddDeptDto;
import com.ocom.common.dto.Department;
import com.ocom.common.dto.ModifyDeptDto;
import com.ocom.common.entity.human.EntityDeptInfo;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.utils.StringUtils;
import com.ocom.human.dao.IDaoDeptInfo;
import com.ocom.human.dao.IDaoPersonnelInfo;
import com.ocom.human.service.DeptInfoService;
import com.ocom.mysql.aspect.DataSourceAspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DeptInfoServiceImpl  extends ServiceImpl<IDaoDeptInfo, EntityDeptInfo> implements DeptInfoService {

    //注入deptInfo 持久层
    @Autowired
    private IDaoDeptInfo deptInfo;

    //personnelInfo 持久层
    @Autowired
    private IDaoPersonnelInfo personnelInfo;

    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comID")
    @Override
    public List<EntityDeptInfo> GetDeptInfo(Long comID, Long deptID,String deptName) {
        QueryWrapper<EntityDeptInfo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotNull(comID)){
            wrapper.eq("com_id",comID);
        }
        if (StringUtils.isNotNull(deptID) && deptID>0){
            wrapper.eq("dept_id",deptID);
        }
        if (StringUtils.isNotEmpty(deptName)){
            wrapper.like("dept_name",deptName);
        }
        return deptInfo.selectList(wrapper);
    }



    /**
     * 校验新增部门名称是否唯一
     *
     * @param deptName 部门名称
     * @return 结果
     */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public String AddDeptNameUnique (Long comId,String deptName,Long parentDeptId) {
        QueryWrapper<EntityDeptInfo> query = Wrappers.query();
        if (StringUtils.isNotNull(comId) ){
            query.eq("com_id",comId);
        }
        if (StringUtils.isNotEmpty(deptName) ){
            query.eq("dept_name",deptName);
        }
        if (StringUtils.isNotNull(parentDeptId) ){
            query.eq("parent_dept_id",parentDeptId);
        }
        query.last("limit 1");
        //校验
        EntityDeptInfo dp = deptInfo.selectOne(query);

        if (StringUtils.isNotNull(dp) && dp.getDeptName().equals(deptName) )   {
            return UserConstants.NOT_UNIQUE;
        }

        return UserConstants.UNIQUE;
    }

    /**
     * 校验部门名称是否唯一
     *
     * @param modifyDeptDto 部门信息
     * @return 结果
     */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public String UpdateDeptNameUnique(ModifyDeptDto modifyDeptDto,Long comId){
        //where dept_name=#{deptName} and parent_id = #{parentId} limit 1
        QueryWrapper<EntityDeptInfo> query = Wrappers.query();
        query.eq("com_id",comId);

        if (StringUtils.isNotEmpty(modifyDeptDto.getDeptName()) ){
            query.eq("dept_name",modifyDeptDto.getDeptName());
        }
        if (StringUtils.isNotNull(modifyDeptDto.getParentDeptId())){
            query.eq("parent_dept_id",modifyDeptDto.getParentDeptId());
        }
        query.last("limit 1");
        //校验
        EntityDeptInfo dp = deptInfo.selectOne(query);

        if (StringUtils.isNotNull(dp) && dp.getDeptName().equals(modifyDeptDto.getDeptName()) &&
                !modifyDeptDto.getDeptId().equals(dp.getDeptId()))   {
            return UserConstants.NOT_UNIQUE;
        }

        return UserConstants.UNIQUE;
    }

    /**
     * 根据部门ID查询信息
     *
     * @param deptId 部门ID
     * @return 部门信息
     */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public EntityDeptInfo selectDeptById (Long deptId)
    {
        return deptInfo.selectById(deptId);
    }

    /**
     * 新增保存部门信息
     *
     * @param addDeptDto 部门信息
     * @return 结果
     */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Transactional
    @Override
    public Long insertDept(AddDeptDto addDeptDto,Long comId) {
        EntityDeptInfo entityDeptInfo = new EntityDeptInfo();
        //封装参数
        entityDeptInfo.setParentDeptId(addDeptDto.getParentDeptId());
        entityDeptInfo.setComId(addDeptDto.getComId());
        entityDeptInfo.setDeptName(addDeptDto.getDeptName());
        entityDeptInfo.setRemark(addDeptDto.getRemark());
        //设置顶级等级 父级id赋值给顶级做等级处理;
        entityDeptInfo.setGrade(1l);
        entityDeptInfo.setOrgin("0");
        if(addDeptDto.getParentDeptId()!=null && addDeptDto.getParentDeptId()>0l){
            QueryWrapper<EntityDeptInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("com_id",addDeptDto.getComId()).eq("dept_id",addDeptDto.getParentDeptId());
            wrapper.last("limit 1");
            EntityDeptInfo info = deptInfo.selectOne(wrapper);
            if(info!=null ){
                entityDeptInfo.setGrade(info.getGrade()+1l);
                entityDeptInfo.setOrgin(info.getOrgin()+","+addDeptDto.getParentDeptId());
            }
        }

        entityDeptInfo.setDeptType(addDeptDto.getDeptType());

        //部门编号deptNo在当前单位下从自然数1开始往后增加
        QueryWrapper<EntityDeptInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("com_id",addDeptDto.getComId()).orderByDesc("dept_no");
        wrapper.last("limit 1");
        EntityDeptInfo info = deptInfo.selectOne(wrapper);
        if (info == null){
            entityDeptInfo.setDeptNo(1L);
            deptInfo.insert(entityDeptInfo);
        }
        else if (StringUtils.isNotNull(info.getDeptNo())){
            entityDeptInfo.setDeptNo(info.getDeptNo()+1);
            deptInfo.insert(entityDeptInfo);
        }else {
            entityDeptInfo.setDeptNo(1L);
            deptInfo.insert(entityDeptInfo);
        }
        return entityDeptInfo.getDeptId();
    }
    /**修改部门
     * @param dept*/
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Transactional
    @Override
    public Long UpdateDept(ModifyDeptDto dept,Long comId) {
        UpdateWrapper<EntityDeptInfo> update = Wrappers.update();
        EntityDeptInfo info = new EntityDeptInfo();
        if (StringUtils.isNotNull(dept.getComId())){
            update.eq("com_id", dept.getComId());
            info.setComId(dept.getComId());
        }
        if (StringUtils.isNotNull(dept.getDeptId())){
            update.eq("dept_id", dept.getDeptId());
            info.setDeptId(dept.getDeptId());
        }
        update.last("limit 1");
        if (StringUtils.isNotEmpty(dept.getDeptName())){
            info.setDeptName(dept.getDeptName());
        }
        if (StringUtils.isNotEmpty(dept.getRemark())){
            info.setRemark(dept.getRemark());
        }
        info.setDeptType(dept.getDeptType());

        return Long.valueOf(deptInfo.update(info,update));

    }

    /**
     * 是否存在子节点
     *
     * @param deptID 部门ID
     * @return 结果
     */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public boolean hasChildByDeptId (Long comId, Long deptID){

        QueryWrapper<EntityDeptInfo> wrapper = new QueryWrapper<>();
        //检查部门是否有下级部门
        wrapper.eq("parent_dept_id",deptID)
                .last("limit 1");
        Integer integer = (deptInfo.selectCount(wrapper));
        return integer > 0 ? true:false;
    }

    /**
     * 查询部门是否存在用户
     *
     * @param deptId 部门ID
     * @return 结果 true 存在 false 不存在
     */
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public boolean checkDeptExistUser (Long comId, Long deptId)
    {
        //select count(1) from sys_user where dept_id = #{deptId} and del_flag = '0'
        QueryWrapper<EntityPersonnelInfo> query = Wrappers.query();
        query.eq("com_id",comId).eq("dept_id",deptId).eq("status", 0);
        Long result = Long.valueOf(personnelInfo.selectCount(query));
        return result > 0 ? true : false;
    }

    /**删除部门*/
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Transactional
    @Override
    public void DelDept(Long comId, Long deptId) {
        deptInfo.deleteById(deptId);
    }

    /**查找部门名称
     * @return*/
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public EntityDeptInfo SelectDeptName(Long deptId, Long comId) {
        return deptInfo.selectById(deptId);
    }

    /*
     * @Description:2.1.6获取下级部门信息
     * @Author: lu 
     * @Date: 2022/4/21 15:31
     * @param comId: 
     * @param deleteDeptDto:  
     * @return: java.util.List<com.ocom.common.entity.human.EntityDeptInfo>
     **/
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public PageInfo<EntityDeptInfo> selectGetDeptInfos(Long comId, Department department) {
        QueryWrapper<EntityDeptInfo> query = Wrappers.query();
        query.select("com_id","dept_id","dept_name","grade","dept_no");
        query.eq("com_id",comId);
        if(department.getDeptId()!=null && department.getDeptId()!=-1){
            query.eq("parent_dept_id",department.getDeptId());
        }
        PageHelper.startPage(department.getPage(),department.getSize());
        List<EntityDeptInfo> pointInfoPageInfo=this.list(query);
        PageInfo<EntityDeptInfo> pageInfo=new PageInfo<>(pointInfoPageInfo);
        return pageInfo;
    }

    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public String selectDeptIds(Long comId, Department department) {
        String bootparentDeptId="";
        QueryWrapper<EntityDeptInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.select("GROUP_CONCAT(dept_id) as parentDeptIds");
        if (department.getDeptId()!=null && department.getDeptId()!=-1){
            query.eq("parent_dept_id",department.getDeptId());
        }
        EntityDeptInfo entityDeptInfo=deptInfo.selectOne(query);

        if (entityDeptInfo==null || entityDeptInfo.getParentDeptIds()==null){
            return bootparentDeptId;
        }
        if (department.getShowLevel()==1 || department.getDeptId()==null || department.getDeptId()==-1){
            return bootparentDeptId=entityDeptInfo.getParentDeptIds();
        }
        boolean bootparentDeptIds=true;
        bootparentDeptId=entityDeptInfo.getParentDeptIds();
        String bootparentDeptIdstr=bootparentDeptId;
        int i=0;
        while (bootparentDeptIds){
            try {
                QueryWrapper<EntityDeptInfo> querys = Wrappers.query();
                querys.eq("com_id",comId);
                querys.select("GROUP_CONCAT(dept_id) as parentDeptIds");
                querys.inSql("parent_dept_id",bootparentDeptIdstr);
                EntityDeptInfo entityDeptInfos=deptInfo.selectOne(querys);
                if (entityDeptInfos==null || entityDeptInfos.getParentDeptIds()==null){
                    return bootparentDeptId;
                }
                bootparentDeptIdstr=entityDeptInfos.getParentDeptIds();
                bootparentDeptId=bootparentDeptId+","+entityDeptInfos.getParentDeptIds();
                if (i==50){
                    bootparentDeptIds=false;
                }
                i++;
            }catch (Exception e){
                bootparentDeptIds=false;
            }
        }
        return bootparentDeptId;
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "companyId")
    public List<EntityDeptInfo> getDeptList(Long companyId, Long deptId) {
        QueryWrapper<EntityDeptInfo> querys = Wrappers.query();
        querys.eq("com_id",companyId);
        if(deptId==null ||  deptId<=0l){
            return this.list(querys);
        }else{
            List<EntityDeptInfo> list=  this.list(querys);
            List<EntityDeptInfo> list2=new ArrayList<>();
            List<Long> ins= new ArrayList<>();
            ins.add(deptId);
            return loop(list,list2,ins);
        }
    }

    @DataSourceAspect(type= DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public Boolean saveArr(Long comId, List<EntityDeptInfo> entityDeptInfos) {
//        if(entityDeptInfos.size()>40){
//            List<List<EntityDeptInfo>> lists = splistList(entityDeptInfos, 30);
//            for (List<EntityDeptInfo> list:lists){
//                this.saveBatch(list);
//            }
//        }
        return   this.saveBatch(entityDeptInfos);
    }

    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB)
    public List<EntityDeptInfo> getByIds(Long companyId, List<Long> ids) {
        return this.list(Wrappers.lambdaQuery(EntityDeptInfo.class).eq(EntityDeptInfo::getComId,companyId).in(EntityDeptInfo::getDeptId,ids));
    }

    //将List拆分为多个小list集合的实现代码
    public static <T> List<List<T>> splistList(List<T> list,int subNum) {
        List<List<T>> tNewList = new ArrayList<List<T>>();
        int priIndex = 0;
        int lastPriIndex = 0;
        int insertTimes = list.size()/subNum;
        List<T> subList = new ArrayList<>();
        for (int i = 0;i <= insertTimes;i++) {
            priIndex = subNum*i;
            lastPriIndex = priIndex + subNum;
            if (i == insertTimes) {
                subList = list.subList(priIndex,list.size());
            } else {
                subList = list.subList(priIndex,lastPriIndex);
            }
            if (subList.size() > 0) {
                tNewList.add(subList);
            }
        }
        return tNewList;
    }

    //递归操作
    //循环出有用部门树
    public List<EntityDeptInfo>  loop(List<EntityDeptInfo> list1,List<EntityDeptInfo> list2,List<Long> ins){
        int before = ins.size();
        for (EntityDeptInfo entityDeptInfo:list1){
            if(ins.contains(entityDeptInfo.getDeptId()) || ins.contains(entityDeptInfo.getParentDeptId())){
                List<Object> newList = list2.stream().map(EntityDeptInfo::getDeptId).collect(Collectors.toList());
                if(!newList.contains(entityDeptInfo.getDeptId())){
                    list2.add(entityDeptInfo);
                    ins.add(entityDeptInfo.getDeptId());
                }
            }
        }
        int after = ins.size();
        //无新增 返回
        if(before==after){
            return  list2;
        }else{
            return loop(list1,list2,ins);
        }
    }

}
